using System;

namespace SharpMud.LPC
{
	public class String : LPC.Object
	{
		#region Private Members	
		private string _Value;
		#endregion

		#region Constructors
		public String()
			:this(0)
		{
		}

		public String(string value)
		{
			_Value = value;
		}

		public String(int zero)
		{
			_Value = null;
		}
		#endregion
		
		public object Value
		{
			get
			{
				if(_Value==null)
					return ((object)((int)0));
				else
					return _Value;
			}
			set
			{
				if(value is string)
				{
					_Value = (string)value;
					string tv = _Value.Trim();
					if(tv.StartsWith("\"") && tv.EndsWith("\""))
					{
						_Value = tv.Substring(1,tv.Length-2);
					}
				}
				else if(
					((value is int) || (value is Int16) || (value is Int32) || (value is Int64)
					|| (value is float) || (value is double) )
					&& ((int)value==0))
				{
					_Value = null;
				}
				else if(
					((value is int) || (value is Int16) || (value is Int32) || (value is Int64)
					|| (value is float) || (value is double) ))
				{
					throw new ArgumentOutOfRangeException("value",(int)value,"An String cannot be assigned a number other than ZERO.");
				}
				throw new ArgumentException("An String cannot be assigned anything other than a string or a numeric type with value 0.");
			}
		}

        public static bool TryParse(char[] text, ref int index, out LPC.Object result)
        {
            int i2 = index;
            if (text[i2] != '"')
            {
                result = null;
                return false;
            }

            System.Text.StringBuilder sb = new System.Text.StringBuilder();

            for (i2 = i2 + 1; i2 < text.Length; i2++)
            {
                if (text[i2] == '"')
                    break;
                sb.Append(text[i2]);
            }
            if (text[i2] != '"')
                throw new InvalidLpcFormatException();
            
            index = i2+1;
            result = new LPC.String(sb.ToString());
            return true;
        }

        public override string ToParsableString()
		{
			if(_Value==null)
				return ((int)0).ToString();
			else
				return "\"" + _Value + "\"";
		}

        public static explicit operator Integer(String val)
        {
            if ( val._Value == null )
                return new Integer(0);
            else
                throw new InvalidCastException("You cannot convert a non-zero String to an Integer.");
        }
        public static explicit operator int(String val)
        {
            if (val._Value == null)
                return 0;
            else
                throw new InvalidCastException("You cannot convert a non-zero String to an integer.");
        }
        public static explicit operator String(int val)
        {
            if (val == 0)
                return new String(0);
            else
                throw new InvalidCastException("You cannot convert a non-zero integer to an String.");
        }
        public static explicit operator string(String val)
        {
            if (val._Value == null)
                return ((int)0).ToString();
            else
                return val._Value.ToString();
        }

        public static explicit operator String(string val)
        {
            return new String(val);
        }

        protected override Object Clone()
        {
            if (this._Value == null)
                return new String(0);
            else
                return new String(this._Value);
        }
	}
}
